package cn.virens.app.database;

import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.virens.common.CloseableUtil;

public abstract class DatabaseExecutorImpl<D extends DatabaseConnoction> implements DatabaseExecutor {
	protected final static Logger logger = LoggerFactory.getLogger(DatabaseExecutorImpl.class);

	protected abstract D getConnection() throws SQLException;

	@Override
	public <B> B execute(DatabaseQueryExecute<B> execute) {
		B result = null;
		D connoction = null;

		try {
			connoction = getConnection();

			// 执行查询
			result = execute.execute(connoction);
		} catch (Exception e) {
			throw new DatabaseException(e);
		} finally {
			CloseableUtil.close(connoction);
		}
		return result;
	}

	@Override
	public <B> B transactionExecute(DatabaseQueryExecute<B> execute) {
		B result = null;
		D connoction = null;

		try {
			connoction = getConnection();
			connoction.setAutoCommit(false);

			// 执行查询
			result = execute.execute(connoction);

			// 判断是否需要回滚
			if (connoction.isRollbackOnly()) {
				connoction.rollback();
			} else {
				connoction.commit();
			}
		} catch (Exception e) {
			try {
				connoction.rollback();
			} catch (Exception e2) {
				logger.error("回滚异常:" + e2.getMessage(), e2);
			}

			throw new DatabaseException(e);
		} finally {
			CloseableUtil.close(connoction);
		}

		return result;
	}
}
